package com.xncoding.pos.controller;

import com.xncoding.pos.async.AsyncException;
import com.xncoding.pos.common.model.ResultGenerator;
import com.xncoding.pos.common.model.ResultModel;
import com.xncoding.pos.service.GuavaAsyncTest;
import com.xncoding.pos.service.thread.AsyncTaskService;
import com.xncoding.pos.service.thread.original.MyThreadFromThread;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.Future;

@RestController
@Slf4j
public class ThreadController {

    @Resource
    AsyncTaskService asyncTaskService;

    //@Async用在接口上,也可以实现异步
    @Resource
    GuavaAsyncTest guavaAsyncTest;

    @GetMapping("/guavaAsyncTest")
    public void guavaAsyncTest() {
        guavaAsyncTest.futureTest();
    }

    @GetMapping("/asyncTest1")
    @ApiOperation("注解式异步实现")
    public ResultModel asyncTest1() {
        this.asyncTaskService.dealNoReturnTask();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/asyncTest2/{a}")
    @ApiOperation(value = "异步执行:ExecutorService", notes = "1:future,2:没有返回值 ,3:submit+Callable")
    public ResultModel asyncTest2(@PathVariable int a) {
        if (a == 1) {
            this.asyncTaskService.threadTest1();
        } else if (a == 2) {
            this.asyncTaskService.threadTest2();
        } else {
            this.asyncTaskService.threadTest3();
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/invokeTest1")
    @ApiOperation(value = "多任务执行1", notes = "")
    public ResultModel invokeTest1() {
        asyncTaskService.invokeTest1();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/invokeTest2")
    @ApiOperation(value = "多任务执行2", notes = "")
    public ResultModel invokeTest2() {
        asyncTaskService.invokeTest2();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/invokeTest3")
    @ApiOperation(value = "多任务执行3", notes = "")
    public ResultModel invokeTest3() {
        asyncTaskService.invokeTest3();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/asyncTest3")
    @ApiOperation(value = "继承Thread类，实现多线程", notes = "继承Thread类")
    public ResultModel asyncTest3() {
        // 创建异步线程
        MyThreadFromThread myThreadFromThread = new MyThreadFromThread();

        // 启动异步线程
        myThreadFromThread.start();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/threadPoolTaskExecutorTest")
    @ApiOperation(value = "推荐使用：线程池异步执行", notes = "")
    public ResultModel threadPoolTaskExecutorTest() {
        asyncTaskService.threadPoolTaskExecutorTest();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/waitAllSuccess")
    @ApiOperation(value = "异步任务都执行完", notes = "")
    public ResultModel waitAllSuccess() {
        asyncTaskService.allDone1();
        // asyncTaskService.allDone2();
        // asyncTaskService.allDone();
        // asyncTaskService.allDone3();
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/asyExceptionTest")
    @ApiOperation("异步执行，异常处理")
    public ResultModel excTest() {
        try {
            this.asyncTaskService.doException();
        } catch (AsyncException e) {
            log.error("asyExceptionTest异常信息:{}", e.getMessage());
        }

        return ResultGenerator.genFailResult("执行失败");
    }

    @GetMapping("/doFuture/{i}")
    @ApiOperation("注解式实现-带有返回值的异步处理")
    public ResultModel doFuture(@PathVariable int i) {
        Future<String> stringFuture = asyncTaskService.futureTest(i);
        try {
            log.info("------处理其他业务-----");
            Thread.sleep(300);
            log.info("======处理其他业务完成====");

            boolean done = stringFuture.isDone();
            while (done) {
                log.warn("判断线程是否结束-----打印日志------{}", done);
            }

            String s = stringFuture.get();
            log.error("Future线程的值-----打印日志------{}", s);

            return ResultGenerator.genSuccessResult(s);
        } catch (Exception e) {
            log.error("异常信息:{}", e.getMessage());
        }
        return ResultGenerator.genFailResult("执行失败");

    }

    @GetMapping("/doFutureExceptTest")
    @ApiOperation("带有返回值的异步处理：异常")
    public ResultModel futureExcept() {
        try {
            Future<String> future = asyncTaskService.futureExcept();
            boolean done = future.isDone();
            log.info("是否结束-----打印日志------{}", done);
            String s = future.get();
            log.info("执行结果-----打印日志------{}", s);

            return ResultGenerator.genSuccessResult();
        } catch (Exception e) {
            log.error("异常信息:{}", e.getMessage());
        }

        return ResultGenerator.genFailResult("执行失败");
    }


    @GetMapping("/sleepTest")
    @ApiOperation("请求超时测试")
    public ResultModel sleepTest(@RequestParam Integer sleepSeconds) {
        try {
            Thread.sleep(sleepSeconds);
            log.info("请求超时测试-----打印日志------{}", sleepSeconds);
            return ResultGenerator.genSuccessResult();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ResultGenerator.genFailResult("执行失败");
    }

}
